home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvitops / code.c < prev    next >
C/C++ Source or Header  |  1991-01-25  |  10KB  |  452 lines

  1. #include "dvitops.h"
  2.  
  3. static char rcsid[] = "$Header: /usr/jjc/dvitops/RCS/code.c,v 1.5 90/08/14 13:07:42 jjc Rel $";
  4.  
  5. static struct {
  6.     char *name;
  7.     int width;
  8.     int height;
  9. } paper_table[] = 
  10. {
  11. "letter", 612, 792,
  12. "lettersmall", 612, 792,
  13. "a4", 595, 842,
  14. "A4", 595, 842,
  15. "a4small", 595, 842,
  16. "legal", 612, 1008,
  17. "b5", 516, 729,
  18. "b4", 729, 1032,
  19. "tabloid", 792, 1224,
  20. "ledger", 1224, 792,
  21. "statement", 396, 612,
  22. "executive", 540, 720,
  23. "a3", 842, 1190,
  24. "a5", 420, 595,
  25. "folio", 612, 936,
  26. "quarto", 610, 780,
  27. "10x17", 720, 1224, 
  28. NULL };
  29.  
  30. #define MAXCOLS 70
  31.  
  32. static FILE *psfp;
  33. static int cols = 0; /* the number of characters on the current line */
  34.  
  35. #define NS 200
  36. typedef struct string {
  37.     size_t i; /* index into pool */
  38.     int n; /* number of characters */
  39.     int region;
  40.     integer h;
  41.     integer v;
  42.     struct string *next;
  43. } STRING;
  44.  
  45. struct rule {
  46.     int region;
  47.     integer a,b,h,v;
  48.     struct rule *next;
  49. } *rule_list = NULL;
  50.  
  51. static unsigned char *pool = NULL;
  52. static size_t pool_size = 0, pool_used = 0;
  53.  
  54. STRING *string_list[MAXFONTS]; /* one list of strings for each font */
  55.  
  56. STRING *free_string_list;
  57.  
  58. #ifdef PROTO
  59. void ps_string(unsigned char *s, int n);
  60. void print_string_list(STRING *s);
  61. static void print_rule_list(void);
  62. #else
  63. void ps_string();
  64. void print_string_list();
  65. static void print_rule_list();
  66. #endif
  67.  
  68. static int page_number = 0;
  69. int landscape = FALSE;
  70. int magnification = 0;
  71.  
  72. void print_string_list(s)
  73. STRING *s;
  74. {
  75.     int cc;
  76.     integer  v;
  77.     integer ox = 0, oy = 0; /* current origin */
  78.     int r = NO_REGION; /* the current region */
  79.     if (s == NULL)
  80.         return;
  81.     v = s->v + 1;  /* use the 'Z' command not the 'X' command */
  82.     while (s != NULL) {
  83.         if (s->region != r) {
  84.             fprintf(psfp, "%% region %d\n", s->region);
  85.             if (r != NO_REGION)
  86.                 fputs("grestore\n", psfp);
  87.             if (s->region != NO_REGION) {
  88.                 fputs("gsave\n", psfp);
  89.                 do_transform(s->region, &ox, &oy, psfp);
  90.             }
  91.             else
  92.                 ox = oy = 0;
  93.             r = s->region;
  94.             v = s->v + 1; /* use the 'Z' command not the 'X' command */
  95.         }
  96.         if (s->v == v) {
  97.             cols = put_dim((long)(s->h - ox), psfp);
  98.             cc = 'X';
  99.         }
  100.         else {
  101.             cols = put_dim((long)(s->h - ox), psfp);
  102.             putc(' ', psfp);
  103.             cols++;
  104.             cols += put_dim((long)(s->v - oy), psfp);
  105.             cc = 'Z';
  106.         }
  107.         v = s->v;
  108.         ps_string(pool + s->i, s->n);
  109.         putc(cc, psfp);
  110.         putc('\n', psfp);
  111.         s = s->next;
  112.     }
  113.     if (r != NO_REGION)
  114.         fputs("grestore\n", psfp);
  115. }
  116.  
  117. void set_string(p, n, f, h, v)
  118. char *p;
  119. int n, f;
  120. integer h, v;
  121. {
  122.     STRING *s;
  123.     if (!free_string_list) {
  124.         int i;
  125.         free_string_list = (STRING *)malloc(sizeof(STRING)*NS);
  126.         if (free_string_list == NULL)
  127.             out_of_memory();
  128.         for (i = 0; i < NS - 1; ++i)
  129.             free_string_list[i].next = free_string_list + i + 1;
  130.         free_string_list[NS - 1].next = NULL;
  131.     }
  132.     s = free_string_list;
  133.     free_string_list = free_string_list->next;
  134.     if (pool == NULL || pool_size - pool_used < n) {
  135.         if (pool == NULL) {
  136.             pool_size = 5000;
  137.             pool = (unsigned char *)malloc(pool_size);
  138.             pool_used = 0;
  139.         }
  140.         else {
  141.             if (pool_used > SIZE_MAX - n)
  142.                 message(FATAL_ERROR, "too many characters on the page");
  143.             pool_size = pool_used + n;
  144.             if (pool_size > SIZE_MAX/2)
  145.                 pool_size = SIZE_MAX;
  146.             else
  147.                 pool_size <<= 1;
  148.             pool = (unsigned char *)realloc((char *)pool, pool_size);
  149.         }
  150.         if (pool == NULL)
  151.             out_of_memory();
  152.     }
  153.     s->i = pool_used;
  154.     memcpy((char *)(pool + pool_used), p, n);
  155.     pool_used += n;
  156.     s->h = h;
  157.     s->v = v;
  158.     s->n = n;
  159.     s->next = string_list[f];
  160.     s->region = current_region;
  161.     string_list[f] = s;
  162. }
  163.  
  164. void set_rule(a, b, h, v)
  165. integer a, b, h, v;
  166. {
  167.     struct rule *p;
  168.     if (a <= 0 || b <= 0)
  169.         return;
  170.     p = (struct rule *)malloc(sizeof(struct rule));
  171.     if (p == NULL)
  172.         out_of_memory();
  173.     p->a = a;
  174.     p->b = b;
  175.     p->h = h;
  176.     p->v = v;
  177.     p->region = current_region;
  178.     p->next = rule_list;
  179.     rule_list = p;
  180. }
  181.  
  182. static void print_rule_list()
  183. {
  184.     int r = NO_REGION;
  185.     integer ox = 0, oy = 0;
  186.     struct rule *p = rule_list;
  187.     while (p != NULL) {
  188.         struct rule *q = p;
  189.         if (p->region != r) {
  190.             fprintf(psfp, "%% region %d\n", p->region);
  191.             if (r != NO_REGION)
  192.                 fputs("grestore\n", psfp);
  193.             if (p->region != NO_REGION) {
  194.                 fputs("gsave\n", psfp);
  195.                 do_transform(p->region, &ox, &oy, psfp);
  196.             }
  197.             else
  198.                 ox = oy = 0;
  199.             r = p->region;
  200.         }
  201.         put_dim((long)(p->a), psfp);
  202.         putc(' ', psfp);
  203.         put_dim((long)(p->b), psfp);
  204.         putc(' ', psfp);
  205.         put_dim((long)(p->h - ox), psfp);
  206.         putc(' ', psfp);
  207.         put_dim((long)(p->v - oy), psfp);
  208.         fputs(" R\n", psfp);
  209.         p = p->next;
  210.         free((char *)q);
  211.     }
  212.     rule_list = NULL;
  213.     if (r != NO_REGION)
  214.         fputs("grestore\n", psfp);
  215. }
  216.  
  217. void eop(page)
  218. struct page_info *page;
  219. {
  220.     char page_label[100];
  221.     int i, j;
  222.     char *ptr;
  223.     int page_height, page_width;
  224.     for (i = 0; paper_table[i].name != NULL; i++)
  225.         if (strcmp(paper_table[i].name, page->paper) == 0)
  226.             break;
  227.     if (paper_table[i].name == NULL) {
  228.         page_height = paper_table[0].height;
  229.         page_width = paper_table[0].width;
  230.         message(ERROR, "unrecognised page type %s", optarg);
  231.     }
  232.     else {
  233.         page_height = paper_table[i].height;
  234.         page_width = paper_table[i].width;
  235.     }
  236.     ptr = page_label;
  237.     for (i = 9; page->count[i] == 0 && i > 0; --i)
  238.         ;
  239.     for (j = 0; j < i; ++j) {
  240.         sprintf(ptr, "%ld.", (long)(page->count[j]));
  241.         ptr += strlen(ptr);
  242.     }
  243.     sprintf(ptr, "%ld", (long)page->count[i]);
  244.     if (!quiet) 
  245.         fprintf(stderr, "[%s", page_label);
  246.     ++page_number;
  247.     fprintf(psfp, "\n%%%%Page: %s %d\n", page_label, page_number);
  248.     fputs("dvitops begin\n", psfp);
  249.     fprintf(psfp, "/#copies %d def BP\n", page->copies);
  250.     p_form_list(psfp);
  251.     if (landscape) {
  252.         int n;
  253.         fprintf(psfp, "%d landscape\n", page_width);
  254.         n = page_height;
  255.         page_height = page_width;
  256.         page_width = n;
  257.         landscape = FALSE;
  258.     }
  259.     if (magnification > 0) {
  260.         page->mag = magnification;
  261.         magnification = 0;
  262.     }
  263.     fprintf(psfp, "%ld ", (long)(page->num));
  264.     put_dim((long)(page->den), psfp);
  265.     fprintf(psfp, " %d %g %g %d SC\n", 
  266.             page->mag, page->hoffset, page->voffset, page_height);
  267.     p_inline_list(psfp);
  268.     p_import_list(psfp, page);
  269. #ifdef TPIC_SUPPORT
  270.     p_tpic_list(psfp, page);
  271. #endif
  272.     print_rule_list();
  273.     for (j = 0; j < MAXFONTS; ++j) {
  274.         int emitted = FALSE;
  275.         for (i = j; i != EOF; i = same_font(i)) {
  276.             STRING *p = NULL;
  277.             STRING *q = string_list[i];
  278.             STRING *last = q;
  279.             if (string_list[i] == NULL)
  280.                 continue;
  281.             /* reverse the string list */
  282.             while (q != NULL) {
  283.                 STRING *temp = q;
  284.                 q = q->next;
  285.                 temp->next = p;
  286.                 p = temp;
  287.             }
  288.             if (!f_is_blank(i)) {
  289.                 if (!emitted) {
  290.                     fputs("BO\n", psfp);
  291.                     f_emit(i, psfp);
  292.                     emitted = TRUE;
  293.                 }
  294.                 f_set(i, psfp);
  295.                 print_string_list(p);
  296.             }
  297.             last->next = free_string_list;
  298.             free_string_list = p;
  299.             string_list[i] = NULL;
  300.         }
  301.         if (emitted)
  302.             fputs("EO\n", psfp);
  303.     }
  304.     pool_used = 0;
  305.     fputs("\nEP end", psfp);
  306.     if (ferror(psfp))
  307.         message(FATAL_ERROR, "write error: disk full?");
  308.     if (!quiet)
  309.         fputs("] ", stderr);
  310.     pool_used = 0;
  311.     current_region = NO_REGION;
  312.     nregions = 0;
  313. }
  314.  
  315. void trailer()
  316. {
  317.     fputs("\n%%Trailer\n", psfp);
  318.     if (!quiet)
  319.         fputc('\n', stderr);
  320. }
  321.  
  322. void prologue(fp, npages, is_reverse, paper)
  323. FILE *fp;
  324. int npages, is_reverse;
  325. char *paper;
  326. {
  327.     time_t t;
  328.     psfp = fp;
  329.     (void)time(&t);
  330.     fputs("%!PS-Adobe-2.0\n", psfp);
  331.     fputs("%%Creator: dvitops\n", psfp);
  332.     f_comment(psfp);
  333.     fprintf(psfp, "%%%%CreationDate: %s", ctime(&t));
  334.     fprintf(psfp, "%%%%DocumentPaperSizes: %s\n", paper);
  335.     fprintf(psfp, "%%%%Pages: %d %d\n", npages, (is_reverse ? -1 : 1));
  336.     fputs("%%EndComments\n", psfp);
  337.     p_special_prologues(psfp);
  338.     if (include_file("dvitops.pro", psfp) == EOF)
  339.         message(FATAL_ERROR, "can't open dvitops.pro");
  340.     fputs("dvitops begin\n", psfp);
  341.     f_prologue(psfp);
  342.     fputs("end\n", psfp);
  343.     fputs("%%EndProlog\n", psfp);
  344.     fprintf(psfp, "%%%%BeginSetup\n");
  345.     fprintf(psfp, "%%%%PaperSize: %s\n", paper);
  346.     fprintf(psfp, "%%%%EndSetup\n");
  347. }
  348.  
  349.  
  350. /* we asssume all seven-bit printable ascii characters are representable in the
  351.    host character set */
  352.  
  353. #define ASCII_LEFT_PARENTHESIS 050
  354. #define ASCII_RIGHT_PARENTHESIS 051
  355. #define ASCII_BACKSLASH 0134
  356.  
  357. void ps_string(s, n)
  358. unsigned char *s;
  359. int n;
  360. {
  361.     cols++;
  362.     putc('(', psfp);
  363.     while (n--) {
  364.         unsigned char c = *s++;
  365.         if (c == ASCII_LEFT_PARENTHESIS 
  366.             || c == ASCII_RIGHT_PARENTHESIS 
  367.             || c == ASCII_BACKSLASH) {
  368.             if (cols + 2 > MAXCOLS)
  369.                 cols = 0, fputs("\\\n", psfp);
  370.             fputc('\\', psfp); fputc(XCHAR(c), psfp);
  371.             cols += 2;
  372.         }
  373.         else if (c >= 040 && c < 0177) {
  374.             if (cols + 1 > MAXCOLS)
  375.                 cols = 0, fputs("\\\n", psfp);
  376.             putc(XCHAR(c), psfp);
  377.             cols++;
  378.         }
  379.         else {
  380.             if (cols + 4 > MAXCOLS)
  381.                 cols = 0, fputs("\\\n", psfp);
  382.             fprintf(psfp, "\\%03o", c);
  383.             cols += 4;
  384.         }
  385.     }
  386.     putc(')', psfp);
  387. }
  388.  
  389. static int fixed_point = 4;
  390.  
  391. #define LONG_DIGITS 10
  392.  
  393. int put_dim(n, fp)
  394. long n;
  395. FILE *fp;
  396. {
  397.     int len;
  398.     /* room for a -, LONG_DIGITS digits, a decimal point,
  399.        and a terminating '\0' */
  400.     char buf[LONG_DIGITS + 3];            
  401.     char *p = buf + LONG_DIGITS + 2;
  402.     int point = 0;
  403.     buf[LONG_DIGITS + 2] = '\0';
  404.     if (n >= 0) {
  405.         do {
  406.             *--p = '0' + (n % 10);
  407.             n /= 10;
  408.             if (++point == fixed_point)
  409.                 *--p = '.';
  410.         } while (n != 0 || point < fixed_point);
  411.     }
  412.     else {                        /* n < 0 */
  413.         do {
  414.             *--p = '0' - (n % 10);
  415.             n /= 10;
  416.             if (++point == fixed_point)
  417.                 *--p = '.';
  418.         } while (n != 0 || point < fixed_point);
  419.         *--p = '-';
  420.     }
  421.     if (fixed_point > 0) {
  422.         char *q;
  423.         /* there must be a dot, so this will terminate */
  424.         for (q = buf + LONG_DIGITS + 2; q[-1] == '0'; --q)
  425.             ;
  426.         if (q[-1] == '.') {
  427.             if (q - 1 == p) {
  428.                 q[-1] = '0';
  429.                 q[0] = '\0';
  430.             }
  431.             else
  432.                 q[-1] = '\0';
  433.         }
  434.         else
  435.             *q = '\0';
  436.     }
  437.     len = strlen(p);
  438.     fputs(p, fp);
  439.     return len;
  440. }
  441.  
  442. /*
  443. Local Variables:
  444. tab-width: 4
  445. c-indent-level: 4
  446. c-continued-statement-offset: 4
  447. c-brace-offset: -4
  448. c-argdecl-indent: 0
  449. c-label-offset: -4
  450. End:
  451. */
  452.